package com.caimiao.miao.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.PopupWindow;

import com.caimiao.miao.R;
import com.caimiao.miao.library.utils.PixelUtil;

/**
 * Created by cachowu on 2016/10/21.
 */

public class ISpinner extends android.support.v7.widget.AppCompatCheckBox implements View.OnClickListener {
    private DragWindow mDragWindow;
    private int mYOffset, mXOffset;
    private View mAnchor;
    private int mSpinnerWidth;
    private OnSpinnerItemSelectedListener mOnItemSelectedListener;
    private OnDismissListener mOnDismissListener;
    private boolean isUpdateText = true;

    public ISpinner(Context context) {
        super(context);
        initUI();
    }

    public ISpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
        initUI();
    }

    public ISpinner(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initUI();
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private void initUI() {
        boolean need = hasArrow(getCompoundDrawables()) && hasArrow(getCompoundDrawablesRelative());
        if (need) setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.btn_spinner_arrow, 0);
        setOnClickListener(this);
        setChecked(false);
        mDragWindow = new DragWindow(getContext());
    }

    private boolean hasArrow(Drawable[] dbs) {
        if (dbs == null) return true;
        for (int i = 0; i < dbs.length; i++) {
            if (dbs[i] != null) {
                return false;
            }
        }
        return true;
    }

    private int getSpinnerWidth() {
        if (mSpinnerWidth != 0)
            return mSpinnerWidth;
        else if (mAnchor != null)
            return mAnchor.getMeasuredWidth();
        else
            return getMeasuredWidth();
    }

    private void hideDragWindow() {
        setChecked(false);
        if (mOnDismissListener != null) mOnDismissListener.dismiss();
    }

    @Override
    public void onClick(View v) {
        show(mAnchor == null ? this : mAnchor, mXOffset, mYOffset);
    }

    public void show(View anchor, int xOff, int yOff) {
        hideKeyboard(getContext(), anchor);
        mDragWindow.show(anchor == null ? this : anchor, xOff, yOff);
    }

    public void setUpdateTextEnable(boolean updateText) {
        isUpdateText = updateText;
    }

    public void setAnchor(View anchor) {
        mAnchor = anchor;
    }

    public void setAdapter(ListAdapter adapter) {
        mDragWindow.setAdapter(adapter);
    }

    public void setSpinnerWidth(int mSpinnerWidth) {
        this.mSpinnerWidth = mSpinnerWidth;
    }

    private void setSpinnerText(int position, String text, Object obj) {
        if (isUpdateText) setText(text);
        if (mOnItemSelectedListener != null)
            mOnItemSelectedListener.onSelected(this, position, text, obj);
    }

    public void setOffset(int xOff, int yOff) {
        mXOffset = xOff;
        mYOffset = yOff;
    }

    public void setSelection(int position) {
        if (mDragWindow != null) mDragWindow.setSelection(position);
    }

    public void setOnSpinnerItemSelectedListener(OnSpinnerItemSelectedListener onItemSelectedListener) {
        mOnItemSelectedListener = onItemSelectedListener;
    }

    public void setOnDismissListener(OnDismissListener listener) {
        mOnDismissListener = listener;
    }


    public class DragWindow extends PopupWindow implements AdapterView.OnItemClickListener {
        private ListView mListView;
        private int mLastPosition = -1;
        private int mStatusBarHeight;

        public DragWindow(Context context) {
            super(context);
            View root = LayoutInflater.from(context).inflate(R.layout.pop_spinner_list, null);
            mListView = root.findViewById(R.id.popLvSpinner);
            mListView.setOnItemClickListener(this);
            setContentView(root);
            setBackgroundDrawable(new ColorDrawable(0xffcccccc));
            setOutsideTouchable(true);
            setFocusable(true);
            initSpec();
            //获取status_bar_height资源的ID
            int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                //根据资源ID获取响应的尺寸值
                mStatusBarHeight = getResources().getDimensionPixelSize(resourceId);
            }
        }

        private void initSpec() {
            setWidth(getSpinnerWidth());
            setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        }

        public void setAdapter(ListAdapter adapter) {
            if (adapter instanceof IAdapter) {
                ((IAdapter) adapter).setPopWindow(this);
            }
            mListView.setAdapter(adapter);
        }

        public void setSelection(int position) {
            if (position > -1) mListView.setSelection(position);
            if (mListView.getAdapter() instanceof IAdapter) {
                ((IAdapter) mListView.getAdapter()).setSelection(position);
                mLastPosition = position;
            } else {
                setSpinnerText(position, (String) mListView.getItemAtPosition(position), null);
            }
        }

        public void show(View anchor, int xoff, int yoff) {
            initSpec();
//            showAsDropDown(anchor, xoff, yoff);

//            int[] location = new int[2];
//            anchor.getLocationOnScreen(location);
//            showAtLocation(anchor, Gravity.TOP | Gravity.LEFT, location[0] + xoff, location[1] + anchor.getHeight() + yoff);

            int[] location = new int[2];
            anchor.getLocationInWindow(location);
            int screenHeight = PixelUtil.getScreenHeight(getContext());
            int popHeight = getListHeight();
            int height = anchor.getHeight();
            if (popHeight > (screenHeight - location[1] - height) && (screenHeight - location[1] - height) < (location[1] - mStatusBarHeight)) {//显示在anchor上方
                if (popHeight > location[1] - mStatusBarHeight) {
                    setHeight(location[1] - mStatusBarHeight);
                    showAtLocation(anchor, Gravity.NO_GRAVITY, location[0], mStatusBarHeight);
                } else {
                    showAtLocation(anchor, Gravity.NO_GRAVITY, location[0], location[1] - popHeight);
                }
            } else {//否则显示在anchor下方
                if (Build.VERSION.SDK_INT < 24) {
                    showAsDropDown(anchor, xoff, yoff);
                } else {
                    location = new int[2];                    // 获取控件在屏幕的位置
                    anchor.getLocationOnScreen(location);
                    if (Build.VERSION.SDK_INT == 25) {
                        int tempheight = getHeight();
                        if (tempheight == WindowManager.LayoutParams.MATCH_PARENT || screenHeight <= tempheight) {
                            setHeight(screenHeight - location[1] - anchor.getHeight());
                        }
                    }
                    showAtLocation(anchor, Gravity.NO_GRAVITY, location[0] + xoff, location[1] + anchor.getHeight() + yoff);

                }
            }
        }

        private int getListHeight() {
            ListAdapter listAdapter = mListView.getAdapter();
            if (listAdapter == null) {
                return 0;
            }
            int totalHeight = 0;
            int listViewWidth = getSpinnerWidth();//listView在布局时的宽度
            int widthSpec = MeasureSpec.makeMeasureSpec(listViewWidth, MeasureSpec.AT_MOST);
            for (int i = 0; i < listAdapter.getCount(); i++) {
                View listItem = listAdapter.getView(i, null, mListView);
                listItem.measure(widthSpec, 0);

                int itemHeight = listItem.getMeasuredHeight();
                totalHeight += itemHeight;
            }
            // 减掉底部分割线的高度
            return totalHeight + (mListView.getDividerHeight() * listAdapter.getCount() - 1);
        }

        @Override
        public void dismiss() {
            super.dismiss();
//            if (mListView.getAdapter() instanceof IAdapter) {
//                IAdapter adapter = (IAdapter) mListView.getAdapter();
//                // selection=-1&&lastSelection!=-1表示取消选中, selection>=0&&selection!=lastSelection表示选中
//                int selection = adapter.getSelection();
//                if (selection == -1 && mLastPosition != -1) {
//                    setSpinnerText(selection, "", null);
//                    mLastPosition = adapter.getSelection();
//                } else if (selection >= 0 && selection != mLastPosition) {
//                    mLastPosition = adapter.getSelection();
//                    setSpinnerText(mLastPosition, adapter.getSelection(mLastPosition), adapter.getCurData());
//                }
//            }
            hideDragWindow();
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (mListView.getAdapter() instanceof IAdapter) {
                IAdapter adapter = (IAdapter) mListView.getAdapter();
                // selection=-1&&lastSelection!=-1表示取消选中, selection>=0&&selection!=lastSelection表示选中
                int selection = adapter.getSelection();
                if (selection == -1 && mLastPosition != -1) {
                    setSpinnerText(selection, "", null);
                    mLastPosition = adapter.getSelection();
                } else if (selection >= 0 && selection != mLastPosition) {
                    mLastPosition = adapter.getSelection();
                    setSpinnerText(adapter.getSelection(), adapter.getSelection(mLastPosition), adapter.getCurData());
                }
            } else {
                setSpinnerText(position, (String) parent.getItemAtPosition(position), null);
            }
            dismiss();
        }
    }

    private void hideKeyboard(Context context, View view) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

    public interface OnSpinnerItemSelectedListener<T> {
        void onSelected(View v, int position, String text, T obj);
    }

    public interface OnDismissListener {
        void dismiss();
    }

    /**
     * 当加载的Adapter不能让ListView使用onItemClick监听时，请让Adapter继承此接口，否则不要继承。
     *
     * @param <T>
     */
    public interface IAdapter<T> {
        void setPopWindow(DragWindow window);

        int getSelection();

        String getSelection(int position);

        T getCurData();

        void setSelection(int position);
    }
}
